﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Text.RegularExpressions;

namespace DataAccessComponents
{
    /// <summary>
    /// Klasa odzwierciedlająca tabele "Pracownik" w bazie danych
    /// </summary>
    public class Pracownik : INotifyPropertyChanged, IDataErrorInfo
    {

        private Adres adres;

        public Adres Adres
        {
            get { return adres; }
            set { adres = value; NotifyPropertyChanged("Adres"); czy_zmiana = true; }
        }
        /// <summary>
        /// Id pracownika
        /// </summary>
        private int id_pracownik;

        public int Id_pracownik
        {
            get { return this.id_pracownik; }
            set { this.id_pracownik = value; NotifyPropertyChanged("Id_pracownik"); czy_zmiana = true; }
        }

        /// <summary>
        /// Imie pracownika
        /// </summary>
        private string imie;

        public string Imie
        {
            get { return this.imie; }
            set { this.imie = value; NotifyPropertyChanged("Imie"); czy_zmiana = true; }
        }

        /// <summary>
        /// Nazwisko pracownika
        /// </summary>
        private string nazwisko;

        public string Nazwisko
        {
            get { return this.nazwisko; }
            set { this.nazwisko = value; NotifyPropertyChanged("Nazwisko"); czy_zmiana = true; }
        }

        /// <summary>
        /// Id stanowiska
        /// </summary>
        private int id_stanowiska;

        public int Id_stanowiska
        {
            get { return this.id_stanowiska; }
            set { this.id_stanowiska = value; NotifyPropertyChanged("Id_stanowiska"); czy_zmiana = true; }
        }

        /// <summary>
        /// Nazwa stanowiska
        /// </summary>
        private string nazwa_stanowisko;

        public string Nazwa_stanowisko
        {
            get { return this.nazwa_stanowisko; }
            set { this.nazwa_stanowisko = value; NotifyPropertyChanged("Nazwa_stanowiska"); czy_zmiana = true; }
        }

        /// <summary>
        /// Id uprawnienienia
        /// </summary>
        private int id_uprawnienia;

        public int Id_uprawnienia
        {
            get { return this.id_uprawnienia; }
            set { this.id_uprawnienia = value; NotifyPropertyChanged("Id_uprawnienia"); czy_zmiana = true; }
        }

        /// <summary>
        /// Nazwa uprawnienia
        /// </summary>
        private string nazwa_uprawnienie;

        public string Nazwa_uprawnienie
        {
            get { return this.nazwa_uprawnienie; }
            set
            {
                this.nazwa_uprawnienie = value;
                NotifyPropertyChanged("Nazwa_uprawnienia");
                czy_zmiana = true;
            }
        }

        /// <summary>
        /// Data aktywnosci użytkownika
        /// </summary>
        private DateTime data_aktywnosci;

        public DateTime Data_aktywnosci
        {
            get { return this.data_aktywnosci; }
            set { this.data_aktywnosci = value; NotifyPropertyChanged("Data_aktywnosci"); czy_zmiana = true; }
        }

        /// <summary>
        /// Data rejestracji
        /// </summary>
        private DateTime data_rejestracji;

        public DateTime Data_rejestracji
        {
            get { return this.data_rejestracji; }
            set { this.data_rejestracji = value; NotifyPropertyChanged("Data_rejestracji"); czy_zmiana = true; }
        }

        /// <summary>
        /// Id adresu Pracownika
        /// </summary>
        private int id_adres;

        public int Id_adres
        {
            get { return this.id_adres; }
            set { this.id_adres = value; NotifyPropertyChanged("Id_adres"); czy_zmiana = true; }
        }

       
       

        /// <summary>
        /// Adres email pracownika
        /// </summary>
        private string email;

        public string Email
        {
            get { return this.email; }
            set { this.email = value; czy_zmiana = true; }
        }

        /// <summary>
        /// Id oddziału pracownika
        /// </summary>
        private int id_oddzial;

        public int Id_oddzial
        {
            get { return this.id_oddzial; }
            set { this.id_oddzial = value; czy_zmiana = true; }
        }

        /// <summary>
        /// Obiekt oddziału pracownika
        /// </summary>
        private Oddzial oddzial;

        public Oddzial Oddzial
        {
            get { return this.oddzial; }
            set { this.oddzial = value; czy_zmiana = true; }
        }

        /// <summary>
        /// Haslo MD5
        /// </summary>
        private string haslo;

        public string Haslo
        {
            get { return haslo; }
            set { haslo = value; czy_zmiana = true; }
        }

        /// <summary>
        /// Wyłapywanie zmian
        /// </summary>
        private bool czy_zmiana;

        public bool Czy_zmiana
        {
            get { return czy_zmiana; }
            set { czy_zmiana = value; }
        }

        /// <summary>
        /// Zmienna zawierająca informacje o zablokowniu użytkownika
        /// </summary>
        private bool czy_zablokowany;

        public bool Czy_zablokowany
        {
            get { return this.czy_zablokowany; }
            set { this.czy_zablokowany = value; NotifyPropertyChanged("Czy_zablokowany"); czy_zmiana = true; }
        }

        /// <summary>
        /// Zmienna odpowiada z przechowywanie informacji o usunięciu obiekut
        /// </summary>
        private bool czy_usunosc;

        public bool Czy_usunosc
        {
            get { return this.czy_usunosc; }
            set { this.czy_usunosc = value; NotifyPropertyChanged("Czy_usunosc"); czy_zmiana = true; }
        }

        /// <summary>
        /// Konstruktor tworzący obiekt "Pracownicy"
        /// </summary>
        /// <param name="ip">Id pracownika</param>
        /// <param name="im">Imie</param>
        /// <param name="naz">Nazwisko</param>
        /// <param name="ids">Id stanowiska</param>
        /// <param name="idu">Id uprawnienia</param>
        /// <param name="da">Data aktywności</param>
        /// <param name="dr">Data rejestracji</param>
        /// <param name="ia">Id adresu </param>
        /// <param name="cz">Czy zablokowany</param>
        /// <param name="em">Email</param>
        /// <param name="ad">Adres</param>
        public Pracownik(int ip, string im, string naz, int ids, int idu,
            DateTime da, DateTime dr, int ia, bool cz, string em,Adres ad)
        {
            this.id_pracownik = ip;
            this.imie = im;
            this.nazwisko = naz;
            this.id_stanowiska = ids;
            this.id_uprawnienia = idu;
            this.data_aktywnosci = da;
            this.data_rejestracji = dr;
            this.id_adres = ia;
            this.czy_zablokowany = cz;
            this.email = em;
            this.adres = ad;
            this.czy_zmiana = false;
        }

        public Pracownik()
            : this(0, "", "", 0, 0, new DateTime(1900, 1, 1),
            DateTime.Now, 0, false, "",new Adres())
        { }

        /// <summary>
        /// Funkcja zmieniająca hasło
        /// </summary>
        /// <param name="stareHaslo">Stare hasło</param>
        /// <param name="noweHaslo">Nowe hasło</param>
        /// <param name="idpracownik">Id pracownika do zmiany hasła</param>
        /// <returns></returns>
        public bool zmienHaslo(string stareHaslo, string noweHaslo)
        {
            stareHaslo = GetMd5Hash(stareHaslo);
            if (this.Haslo.Equals(stareHaslo))
            {
                string noweHasloMD5 = GetMd5Hash(noweHaslo);
                this.haslo = noweHasloMD5;
                return true;
            }
            else
            {
                return false;
            }
        }

        public bool ustalHalso(string haslo)
        {
            if (string.IsNullOrEmpty(this.Haslo))
            {                
                string haslotmp = haslo;
                this.Haslo = GetMd5Hash(haslotmp);
                return true;
            }
            else
            {
                return false;
            }
        }

       

        private string GetMd5Hash(string input)
        {
            System.Security.Cryptography.MD5CryptoServiceProvider x = new System.Security.Cryptography.MD5CryptoServiceProvider();
            byte[] bs = Encoding.UTF8.GetBytes(input);
            bs = x.ComputeHash(bs);

            StringBuilder sb = new StringBuilder();
            foreach (byte b in bs)
            {
                sb.Append(b.ToString("x2").ToLower());
            }
            return sb.ToString();
        }


        #region INotifyPropertyChanged Members
        public event PropertyChangedEventHandler PropertyChanged;
        #endregion

        #region Private Helpers
        private void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

            }
        }
        #endregion

        public string Error
        {
            get { return string.Empty; }
        }

        public string this[string propertyName]
        {
            get
            {
                string result = string.Empty;
                propertyName = propertyName ?? string.Empty;
                if (propertyName == "Imie")
                {
                    if (string.IsNullOrEmpty(this.Imie))
                    {
                        result = "Pole \"Imie\" nie może być puste";
                    }
                    else if (Regex.IsMatch(this.Imie, @"[@£_^{}\[~\]|ÆæßÉ!¤%&'()\*\+,-.:;<=>§¿]+"))
                    {
                        result = "Pole \"Imie\" zawiera niedozwolone znaki";
                    }
                    else if (this.Imie.Length < 2)
                    {
                        result = "\"Imie\" jest zakrótkie";
                    }
                }
                else if (propertyName == "Nazwisko")
                {
                    if (string.IsNullOrEmpty(this.Nazwisko))
                    {
                        result = "Pole \"Nazwisko\" nie może być puste";
                    }
                    else if (Regex.IsMatch(this.Nazwisko, @"[@£_^{}\[~\]|ÆæßÉ!¤%&'()\*\+,-.:;<=>§?]+"))
                    {
                        result = "Pole \"Nazwisko\" zawiera niedozwolone znaki";
                    }
                    else if (this.Nazwisko.Length < 2)
                    {
                        result = "\"Nazwisko\" jest zakrótkie";
                    }
                }
                else if (propertyName == "Data_aktywnosci")
                {
                    if (this.Data_aktywnosci.ToShortDateString().Contains('-'))
                    {
                        string[] data = this.Data_aktywnosci.ToShortDateString().Split('-');
                        if (data.Length == 3)
                        {
                            string dataFormat = string.Format("{2}/{1}/{0}", data[0], data[1], data[2]);
                            DateTime dt = new DateTime();
                            if (!DateTime.TryParse(dataFormat, out dt))
                            {
                                result = "Niepoprawna data (dd-mm-rrrr)";
                            }

                        }
                        else
                        {
                            result = "Niepoprawna format daty (dd-mm-rrrr)";
                        }

                    }
                    else if (!this.Data_aktywnosci.ToShortDateString().Contains('-'))
                    {
                        result = "Niepoprawna format daty (dd-mm-rrrr)";
                    }
                }
                else if (propertyName == "Data_rejestracji")
                {
                    if (this.Data_rejestracji.ToShortDateString().Contains('-'))
                    {
                        string[] data = this.Data_rejestracji.ToShortDateString().Split('-');
                        if (data.Length == 3)
                        {
                            string dataFormat = string.Format("{2}/{1}/{0}", data[0], data[1], data[2]);
                            DateTime dt = new DateTime();
                            if (!DateTime.TryParse(dataFormat, out dt))
                            {
                                result = "Niepoprawna data (dd-mm-rrrr)";
                            }

                        }
                        else
                        {
                            result = "Niepoprawna format daty (dd-mm-rrrr)";
                        }

                    }
                    else if (!this.Data_rejestracji.ToShortDateString().Contains('-'))
                    {
                        result = "Niepoprawna format daty (dd-mm-rrrr)";
                    }
                }
                else if (propertyName == "Email")
                {
                    if (string.IsNullOrEmpty(this.Email))
                    {
                        result = "Pole \"Email\" nie może być puste";
                    }
                    else if (!Regex.IsMatch(this.Email, @"^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]{1,})*\.([a-zA-Z]{2,}){1}$"))
                    {
                        result = "Pole \"Email\" zawiera nie poprawny adres email";
                    }
                }
                return result;
            }
        }
    }
}
